package com.admin.web.interceptor;

import com.bayss.core.DokoServerException;
import com.bayss.core.DokoServerExceptionFactor;
import com.bayss.core.entity.rbac.mapper.OBGUserInfoMapper;
import com.bayss.core.service.OperateLogService;
import com.bayss.core.service.RbacService;
import com.bayss.core.util.SpringContextUtil;
import com.bayss.core.util.TokenUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class TokenInterceptor extends HandlerInterceptorAdapter {
    private static Logger logger = LogManager.getLogger();
    private OBGUserInfoMapper userInfoMapper;
    private OperateLogService operateLogService;
    private RbacService rbacService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (userInfoMapper == null) {
            userInfoMapper = SpringContextUtil.getBean(OBGUserInfoMapper.class);
        }
        if (operateLogService == null) {
            operateLogService = SpringContextUtil.getBean(OperateLogService.class);
        }
        if (rbacService == null) {
            rbacService = SpringContextUtil.getBean(RbacService.class);
        }
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        // 执行认证
        String token = request.getHeader("token");// 从 http 请求头中取出 token
        if (token == null || !TokenUtils.verifyToken(token)) {
            logger.error("认证失败，token失效");
            return true;
//            throw new DokoServerException(DokoServerExceptionFactor.token_expire, "认证失败，请重新登入");//错误细节不暴露外部
        }
        Integer userId = TokenUtils.getUserId(token, "user_id");
        if (userInfoMapper.selectByPrimaryKey(userId) == null) {
            logger.error("认证失败，用户不存在");
            throw new DokoServerException(DokoServerExceptionFactor.token_expire, "认证失败，请重新登入");//错误细节不暴露外部
        }

        //1校验用户操作权限
//        boolean isPerm = rbacService.checkUserPermission(userId,request.getRequestURI()); //todo 权限菜单用起来再放开校验
//        if(!isPerm){
//            logger.error("权限验证失败：无权限操作");
//            throw new DokoServerException(DokoServerExceptionFactor.token_expire, "无权限操作，请联系管理员授权");
//        }

        //保存操作记录
        operateLogService.saveOperateLog(userId, request.getRequestURI());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {


    }

}
